package services

import (
	"hg/models"
	"hg/pkg/database"
	"hg/pkg/notice"
	"hg/utils"
	"io/ioutil"
	"mime/multipart"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/google/uuid"
	"github.com/sirupsen/logrus"
)

var uploadIDToFilePath = make(map[string]string)

const (
	uploadFileDir = "temp/upload"
)

// 上传文件到服务器，并返回给前端uuid
func UploadToServer(c *gin.Context) {
	client := utils.GetRedis()
	resp := models.GetDefaultResp()
	file, err := c.FormFile("file")
	if err != nil {
		logrus.Errorln(err)
		return
	}
	uploadID := uuid.NewString()

	fileContent, err := readFileContent(file)
	if err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}
	err = client.HSet("uploaded_files", uploadID, fileContent).Err()
	if err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}

	// filePath := fmt.Sprintf("%s/%s/%s", uploadFileDir, uploadID, file.Filename)
	// if err := c.SaveUploadedFile(file, filePath); err != nil {
	// 	setApiError(c, http.StatusInternalServerError, resp, err)
	// 	return
	// }
	// uploadIDToFilePath[uploadID] = filePath
	resp.Data = uploadID
	c.JSON(http.StatusOK, resp)
}

type UUID struct {
	Uuid string `json:"uuid"`
}

// 接收前端的uuid，上传视频到云存储
func UploadVideoToCloudStorage(c *gin.Context) {
	video := new(models.Videos)
	uploadID := new(UUID)
	resp := models.GetDefaultResp()
	if err := c.ShouldBindBodyWith(&uploadID, binding.JSON); err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}
	object := uploadToCloudStorageByUUID(uploadID.Uuid)
	user := getUserInfo(c)
	if err := c.ShouldBindBodyWith(&video, binding.JSON); err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}
	video.ObjId = object.Id
	video.UserInfo = user.Id
	err := database.InsertOneVideo(video)
	if err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}
	if ok := sendvideoNoticetouser(c, user, video.Title); !ok {
		logrus.Error("send notice failed")
		return
	}
	resp.Data = video
	c.JSON(http.StatusOK, resp)
}

// 接收前端发送的uuid，上传图片到云存储
func UploadImageToCloudStorage(c *gin.Context) {
	resp := models.GetDefaultResp()
	uploadID := new(UUID)
	// uploadID := c.Param("uuid")
	if err := c.ShouldBindJSON(&uploadID); err != nil {
		setApiError(c, http.StatusInternalServerError, resp, err)
		return
	}
	object := uploadToCloudStorageByUUID(uploadID.Uuid)
	resp.Data = object.Id
	c.JSON(http.StatusOK, resp)
}

// 将object对象通过uuid上传到云存储
func uploadToCloudStorageByUUID(uuid string) *models.Object {
	// fileContent, err := client.HGet("uploaded_files", uuid).Result()
	// if err != nil {
	// 	logrus.Errorln("Failed to get file content from Redis: ", err)
	// 	return nil
	// }
	// println(fileContent)

	filePath, exists := uploadIDToFilePath[uuid]
	if !exists {
		logrus.Errorln("File path not exists")
		return nil
	}
	object := InsertObject(filePath)
	delete(uploadIDToFilePath, uuid)
	return object
}

func sendvideoNoticetouser(c *gin.Context, user *models.Userinfo, videoTitle string) bool {
	noticeMsg := &models.NoticeMsg{
		Title:    "稿件上传成功通知",
		Content:  "【沙漏视频】您的视频稿件***" + videoTitle + "***已上传成功，正在等待审核。",
		UserNums: []string{user.Email},
		Type:     "email",
	}
	// if ok, _ := sendEmailCodeToUser(c, noticeMsg); !ok {
	// 	return false
	// }
	err := notice.SendNoticeToUser(noticeMsg)
	if err != nil {
		logrus.Error("send notice to user faile", err)
		return false
	}
	return true
}

func readFileContent(file *multipart.FileHeader) ([]byte, error) {
	fileHeader, err := file.Open()
	if err != nil {
		return nil, err
	}
	defer fileHeader.Close()

	fileContent, err := ioutil.ReadAll(fileHeader)
	if err != nil {
		return nil, err
	}

	return fileContent, nil
}
